#ifndef MQTT_CLIENT_H
#define MQTT_CLIENT_H

#include <stddef.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct mqtt_client mqtt_client_t;

typedef struct mqtt_config {
    const char *host;        // default: from app_config.h (APPCFG_DEFAULT_MQTT_HOST)
    int         port;        // default: from app_config.h (APPCFG_DEFAULT_MQTT_PORT)
    const char *client_id;   // optional, NULL = auto
    const char *username;    // optional
    const char *password;    // optional
    int         keepalive;   // default: 60
    bool        clean_session; // default: true

    // TLS
    bool        tls_enable;  // default: false
    const char *cafile;      // optional when tls_enable
    const char *capath;      // optional when tls_enable
    bool        insecure;    // default: false

    // WebSocket/WSS
    bool        ws_enable;   // default: false; if true, use WebSocket transport
    const char *ws_path;     // default: "/mqtt" when ws_enable
} mqtt_config_t;

// Message: payload may be binary and is not NUL-terminated
typedef void (*mqtt_message_cb)(const char *topic, const void *payload, int len, void *user);
typedef void (*mqtt_connect_cb)(int rc, void *user);

// Fill cfg with safe defaults
void mqtt_config_defaults(mqtt_config_t *cfg);

// Convenience: load from environment variables
// MQTT_HOST / MQTT_PORT / MQTT_CLIENT_ID / MQTT_USERNAME / MQTT_PASSWORD
// MQTT_TLS_ENABLE / MQTT_CAFILE / MQTT_CAPATH / MQTT_INSECURE
void mqtt_config_from_env(mqtt_config_t *cfg);

mqtt_client_t *mqtt_client_new(const mqtt_config_t *cfg, void *user);
void mqtt_client_destroy(mqtt_client_t *c);

// Returns mosquitto error code (0 = success)
int mqtt_client_connect(mqtt_client_t *c);
int mqtt_client_disconnect(mqtt_client_t *c);

// Start/stop internal network thread
int mqtt_client_start(mqtt_client_t *c);
int mqtt_client_stop(mqtt_client_t *c);

// QoS: 0,1,2; retain: 0/1
int mqtt_client_publish(mqtt_client_t *c, const char *topic, const void *payload, int len, int qos, int retain);
// Publish and wait for PUBACK when qos>0; timeout_ms<=0 means no wait
int mqtt_client_publish_sync(mqtt_client_t *c, const char *topic, const void *payload, int len, int qos, int retain, int timeout_ms);
// Records the subscription for auto re-subscribe after reconnect
int mqtt_client_subscribe(mqtt_client_t *c, const char *topic, int qos);

void mqtt_client_set_message_cb(mqtt_client_t *c, mqtt_message_cb cb);
void mqtt_client_set_connect_cb(mqtt_client_t *c, mqtt_connect_cb cb);

int mqtt_client_is_connected(const mqtt_client_t *c);
void *mqtt_client_user(mqtt_client_t *c);
void mqtt_client_set_user(mqtt_client_t *c, void *user);

// Translate mosquitto error code to human-readable string
const char *mqtt_errstr(int code);

// True if WebSocket transport is active
int mqtt_client_uses_ws(const mqtt_client_t *c);

#ifdef __cplusplus
}
#endif

#endif // MQTT_CLIENT_H
